package org.apache.osgimaker.editors;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.util.List;

import org.apache.osgimaker.editors.model.AnalyseReportModel;
import org.apache.osgimaker.editors.pages.ClassCycleListPage;
import org.apache.osgimaker.editors.pages.ClassesListPage;
import org.apache.osgimaker.editors.pages.PackageCycleListPage;
import org.apache.osgimaker.editors.pages.PackagesListPage;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.text.IDocument;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.forms.editor.FormEditor;
import org.eclipse.ui.forms.editor.IFormPage;
import org.eclipse.ui.ide.ResourceUtil;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.IElementStateListener;

/**
 * @author Tiger Gui
 * tigergui@gmail.com - Beijing China
 * 
 */
public class AnalyseReportEditor extends FormEditor implements IResourceChangeListener{

	static final String BUNDLELIST_PAGE = "__bundle_list_page";
	static final String CLASSESLIST_PAGE = "__classes_list_page";
	static final String PackageCycleListPage = "__packge_cycle_page";
	static final String PackageListPage = "__packge_list_page";
	
	private final AnalyseReportModel model = new AnalyseReportModel();
	
	private final AnalyseReportSourceEditor sourcePage = new AnalyseReportSourceEditor("_source_page", this);
	
	private final PropertyChangeListener modelListener = new PropertyChangeListener() {
        public void propertyChange(PropertyChangeEvent evt) {
            if ("cycleList".equals(evt.getPropertyName())) {
                @SuppressWarnings("unchecked")
                List<String> newSubBundles = (List<String>) evt.getNewValue();
                if (newSubBundles != null && !newSubBundles.isEmpty()) {
                } else {
                	AnalyseReportEditor editor = AnalyseReportEditor.this;
                    ensurePageExists(BUNDLELIST_PAGE, new ClassCycleListPage(editor, model, BUNDLELIST_PAGE, "Content"), 0);
                }
            }
        }
    };
	
    @Override
    public void init(IEditorSite site, IEditorInput input)
            throws PartInitException {
        super.init(site, input);
		sourcePage.init(site, input);
		
		setPartName(input.getName());
		
		IResource resource = ResourceUtil.getResource(input);
		if(resource != null) {
		    resource.getWorkspace().addResourceChangeListener(this);
		}

		final IDocumentProvider docProvider = sourcePage.getDocumentProvider();
		IDocument document = docProvider.getDocument(input);
		try {
			model.loadFrom(document);
			model.addPropertyChangeListener(modelListener);
		} catch (IOException e) {
			throw new PartInitException("Error reading editor input.", e);
		}
		
		// Ensure the field values are updated if the file content is replaced
        docProvider.addElementStateListener(new IElementStateListener() {
            public void elementMoved(Object originalElement, Object movedElement) {
            }

            public void elementDirtyStateChanged(Object element, boolean isDirty) {
            }

            public void elementDeleted(Object element) {
            }

            public void elementContentReplaced(Object element) {
                try {
                    System.out.println("--> Content Replaced");
                    model.loadFrom(docProvider.getDocument(element));
                } catch (IOException e) {
                	e.printStackTrace();
                }
            }

            public void elementContentAboutToBeReplaced(Object element) {
            }
        });
    }

    @Override
    protected void addPages() {
       try {
    	if(model.isClassCyclesFlag()) addPage(new ClassCycleListPage(this, model, BUNDLELIST_PAGE, "Cycles"));
    	if(model.isClassListFlag()) addPage(new ClassesListPage(this, model, CLASSESLIST_PAGE, "Classes"));
    	addPage(new PackageCycleListPage(this, model,PackageCycleListPage, "PackageCycles" ));
    	addPage(new PackagesListPage(this, model, PackageListPage,"Packages"));
    	int sourcePageIndex = addPage(sourcePage, getEditorInput());
        setPageText(sourcePageIndex, "Source");
	} catch (PartInitException e) {
		e.printStackTrace();
	}
    }
    
    protected void ensurePageExists(String pageId, IFormPage page, int index) {
        IFormPage existingPage = findPage(pageId);
        if (existingPage != null)
            return;

        try {
            addPage(index, page);
        } catch (PartInitException e) {
           e.printStackTrace();
        }
    }
    
    protected void removePage(String pageId) {
        IFormPage page = findPage(pageId);
        if (page != null) {
            removePage(page.getIndex());
        }
    }
    
    @Override
	public void doSave(IProgressMonitor monitor) {
		if(sourcePage.isActive() && sourcePage.isDirty()) {
			sourcePage.commit(true);
		} else {
			commitPages(true);
			sourcePage.refresh();
		}
		sourcePage.doSave(monitor);
	}

    @Override
    public void doSaveAs() {
        
    }

    @Override
    public boolean isSaveAsAllowed() {
        return false;
    }
    
    @Override
	protected void handlePropertyChange(int propertyId) {
		super.handlePropertyChange(propertyId);
	}

    public AnalyseReportModel getReportModel() {
		return this.model;
	}

	@Override
	public void resourceChanged(IResourceChangeEvent event) {
		
	}

}